package org.ns.summer.core;

import org.ns.summer.core.AnnotationUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class FieldUtils {

    public static List<Field> findFields(Class<?> beanType, Class<?> annotationType) {
        Field[] declaredFields = beanType.getDeclaredFields();
        List<Field> fields = new ArrayList<>();
        for (Field declaredField : declaredFields) {
            if (AnnotationUtils.existAnnotation(declaredField, annotationType)) {
                fields.add(declaredField);
            }
        }
        return fields;
    }

    public static List<Field> findFieldsAll(Class<?> beanType, Class<?> annotationType) {
        List<Field> fields = new ArrayList<>(32);
        List<Class<?>> types = new ArrayList<>(10);
        types.add(beanType);
        for (int i = 0; i < types.size(); i++) {
            Class<?> aClass = types.get(i); // 获得当前操作类
            Field[] declaredFields = aClass.getDeclaredFields(); // 获得当前类的所有字段
            for (Field declaredField : declaredFields) { // 遍历并判断
                if (AnnotationUtils.existAnnotation(declaredField, annotationType)) {
                    fields.add(declaredField);
                }
            }
            Class<?> superClass = aClass.getSuperclass();
            if (superClass != null && superClass != Object.class) {
                types.add(superClass);
            }
        }
        return fields;
    }


    public static void copyFieldValue(Class<?> beanType, Object target, Object proxy) {
       try {
           if (beanType.isAssignableFrom(target.getClass()) && beanType.isAssignableFrom(proxy.getClass())) {
               List<Field> fields = new ArrayList<>(32);
               List<Class<?>> types = new ArrayList<>(32);
               types.add(beanType);
               for (int i = 0; i < types.size(); i++) {
                   Class<?> aClass = types.get(i);
                   Field[] declaredFields = aClass.getDeclaredFields();
                   for (Field declaredField : declaredFields) {
                       if (!declaredField.isAccessible()) {
                           declaredField.setAccessible(true);
                       }
                       Object value = declaredField.get(target);
                       declaredField.set(proxy, value);
                   }
                   Class<?> superClass = aClass.getSuperclass();
                   if (superClass != null && superClass != Object.class) {
                       types.add(superClass);
                   }
               }
           } else {
               throw new RuntimeException("对象类型不一致！！无法copy");
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}
